local skynet = require "skynet"
local filelog = require "filelog"
local cluster = require "skynet.cluster"

require "pubenum"
require "pszenum"

local router

local robotmgr = {
	handler = {},
    robotpool = {},         --机器人池，从robot节点获取500个，缓存在本节点
    robotinfo_list = {},    --运行中机器人的robotinfo数组
}

--当前机器人数
local cur_robot_num = 0
local is_run = true

--创建机器人
function robotmgr.cretae_robot(obj, base_diamond)
    obj = obj or {}
    local robotinfo = robotmgr.handler.get_robotinfo()
    if not robotinfo then
        return
    end
    local logo = robotinfo.logo or "1"
    local sex = robotinfo.sex or  math.random(1, 2)
    local rid = robotinfo.rid or  math.random(111111, 999999)
    local rolename = robotinfo.rolename or "_g" .. rid
    obj.roledata = {
        info = { 
            rolename = rolename,    --名字
            level = 99,              --等级
		    logo = logo,            --头像
		    sex = sex,              --性别
            rid = rid,
            is_test = true,
        },
        money = {
            diamond = 0,
            coin = 0,
            lock_coin = 0,
            lock_diamond = 0,
        },
        gps_addr = robotinfo.gps_addr,
        ip_addr = robotinfo.ip_addr,
    }
    obj.rid = rid
    obj.roledata.money.diamond = base_diamond
    --保存robotinfo，方便回收
    robotmgr.robotinfo_list[rid] = robotinfo
    cur_robot_num = cur_robot_num + 1
    return obj
end

function robotmgr.handler.get_robotinfo()
    if not robotmgr.robotpool or #(robotmgr.robotpool) < 1 then
        if is_run then
            robotmgr.handler.gen_robotinfo(20)
        end
        return nil
    end
    local len = #(robotmgr.robotpool)
    local idx = math.random(1,len)
    local robotinfo = robotmgr.robotpool[idx]
    robotmgr.robotpool[idx] = robotmgr.robotpool[len]
    robotmgr.robotpool[len] = nil
    return robotinfo
end

--移除一个机器人
function robotmgr.remove_robot(rid)
    if not robotmgr.robotinfo_list[rid] then
        return
    end

    robotmgr.delete_robot(rid)
end

function robotmgr.delete_robot(rid)
    if is_run then
        table.insert(robotmgr.robotpool, robotmgr.robotinfo_list[rid])
    end
    cur_robot_num = cur_robot_num - 1
    robotmgr.robotinfo_list[rid] = nil
end

--移除一些机器人
function robotmgr.remove_robots(rids, num)
    num = num or #rids
    if num <= 0 then
        return
    end

    local cnt = 0
    for _,rid in pairs(rids) do
        robotmgr.remove_robot(rid)
        cnt = cnt + 1
        if cnt == num then
            break
        end
    end
end

function robotmgr.handler.gen_robotinfo(num)
    local status,result = skynet.pcall(cluster.call, "robotnode", ".router", "gen_robotinfo", num)
    if status and result then
        for _,robotinfo in pairs(result) do
            table.insert(robotmgr.robotpool, robotinfo)
        end
        return true
    else
        -- filelog.error("gen_robotinfo error:", result)
    	return false
    end
end

function robotmgr.handler.save_robotinfos()
    local robot_infos = {}
    for _, robot_info in ipairs(robotmgr.robotpool) do
        table.insert(robot_infos, robot_info)
    end
    local status,result = skynet.pcall(cluster.call, "robotnode", ".router", "save_robotinfo", robot_infos)
    robotmgr.robotpool = {}
end

function robotmgr.robot_gameend()
    robotmgr.handler.save_robotinfos()
end

---------------------- scheduler ----------------------
local scheduler = {}

function scheduler.add_robot_to_match(match_level, robot_num, base_diamond)
    local match_level = match_level or 1
    local robot_num = robot_num or 1
    local base_diamond = base_diamond or 10
    for i = 1, robot_num do
        local robot = robotmgr.cretae_robot({}, base_diamond)
        if robot then
            ---进入匹配队列
            local request = {
                match_type = match_level,
            }
            router.entermatchtable(robot.rid, robot.roledata, request)
        -- else
        --     filelog.error("add_robot_to_match: not enough robot!")
        end
    end
end

function scheduler.robotentermatchtable(match_level, robotnum, enter_score)
    local min = enter_score * 2
    local max = enter_score * 5
    local moneyvalue = math.random(min, max)
    scheduler.add_robot_to_match(match_level, robotnum, moneyvalue)
end

function scheduler.check_alltableinfo()
	local status, result = skynet.pcall(router.get_alltableinfo)
    if status then
        if result.match_infos then
            for level, info in pairs(result.match_infos) do
                -- if info.game_type == 1 and info.base_score == 50 then
                    -- if info.cur_total_player < 2 and info.cur_robot_num < 1 and info.waiting_robot == 1 then
                    --     scheduler.robotentermatchtable(level, 1)
                    -- end

                    if info.cur_robot_num < 1 and info.waiting_player <= 1 and info.waiting_robot == 0 then
                        -- filelog.debug("check_alltableinfo:", level, info.cur_robot_num, info.waiting_player, info.waiting_robot, info.unfull_table_num)
                        if info.unfull_table_num == 0 then
                            scheduler.robotentermatchtable(level, 1, info.enter_score)
                        end
                    end
                -- end
            end
        end
    else
        filelog.error(result)
    end
    -- filelog.debug("check_alltableinfo:", result)
end

--设置机器人状态
function robotmgr.set_game_robot_state(newstate)
    is_run = newstate
    if not is_run then
        robotmgr.robot_gameend()
    end
    -- filelog.debug("set_game_robot_state: ", is_run)
end

--获得机器人状态
function robotmgr.get_game_robot_state()
    return is_run
end

--获得机器人数目
function robotmgr.get_game_robot_num()
    return cur_robot_num
end

function robotmgr.monitor()
	skynet.fork(function()
        while true do
        	skynet.sleep(10 * 100)
            -- 定时拉取游戏所有桌子信息
            if is_run then
                pcall(scheduler.check_alltableinfo)
            end
        end
    end)
end

function robotmgr.start(base)
    router = base
	skynet.fork(function()
		local status = robotmgr.handler.gen_robotinfo(20)
		while status == false do
			skynet.sleep(200)
			status = robotmgr.handler.gen_robotinfo(20)
		end
    end)
    
    robotmgr.monitor()
end

return robotmgr